package file

import (
	"context"
	"encoding/json"
	"github.com/wailsapp/wails/v2/pkg/runtime"
	"io"
	"os"
)

const (
	TypeRead  = "read"
	TypeWrite = "write"
)

type Request struct {
	Channel string
	Type    string
	Payload interface{}
}

type ReadResponse struct {
	Data  interface{}
	Error string
}

type ReadRequest struct {
	Channel string
	Type    string
	Payload ReadRequestOption
}

type ReadRequestOption struct {
	Path string
}

type WriteResponse struct {
	Error string
}

type WriteRequest struct {
	Channel string
	Type    string
	Payload WriteRequestOption
}

type WriteRequestOption struct {
	Path string
	// 前端传的base64 会被转为 []byte
	Data []byte
}

const EventName = "file"

func EventsHandler(ctx context.Context, optionalData ...interface{}) {
	baseRequest := new(Request)
	err := json.Unmarshal([]byte(optionalData[0].(string)), baseRequest)
	if err != nil {
		return
	}
	runtime.LogDebugf(ctx, "%+v", baseRequest)

	module := baseRequest.Type

	switch module {
	case TypeWrite:
		request := &WriteRequest{}
		err := json.Unmarshal([]byte(optionalData[0].(string)), request)
		defer func() {
			runtime.EventsEmit(ctx, baseRequest.Channel, WriteResponse{
				Error: errorString(err),
			})
		}()
		err = WriteFile(request.Payload.Path, request.Payload.Data)
	case TypeRead:
		request := &ReadRequest{}
		var data []byte
		err := json.Unmarshal([]byte(optionalData[0].(string)), request)
		defer func() {
			runtime.EventsEmit(ctx, baseRequest.Channel, ReadResponse{
				Data:  data,
				Error: errorString(err),
			})
		}()
		data, err = ReadFile(request.Payload.Path)
	}
}

func WriteFile(path string, data []byte) error {
	file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	defer func() {
		_ = file.Close()
	}()

	if err != nil {
		return err
	}

	_, err = file.Write(data)

	return err
}

func ReadFile(path string) ([]byte, error) {
	file, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm)
	defer func() {
		_ = file.Close()
	}()

	if err != nil {
		return nil, err
	}

	return io.ReadAll(file)
}

func errorString(err error) string {
	if err != nil {
		return err.Error()
	} else {
		return ""
	}
}
